
#include <QDebug>
#include "myopenglwidget.h"

MyOpenGLWidget::MyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}

void MyOpenGLWidget::initializeGL()
{
    float vertices[] = {
        0.5f, 0.5f, 0.0f,    1.0f, 0.0f, 0.0f,    1.0f, 1.0f,  //right top
        0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,    1.0f, 0.0f,  //right bottom
        -0.5f, -0.5f, 0.0,   0.0f, 0.0f, 1.0f,    0.0f, 0.0f,  //left bottom
        -0.5f, 0.5f, 0.0f,   1.0f, 1.0f, 1.0f,    0.0f, 1.0f,  //left top
    };

    unsigned int indices[] = {
        0, 1, 3,
        1, 2, 3,
    };

    initializeOpenGLFunctions();

    vao = new VAO(vertices, sizeof(vertices)/sizeof(*vertices),
                  indices, sizeof(indices)/sizeof(*indices));
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/resource/vert.glsl");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/resource/frag.glsl");
    bool result = shaderProgram.link();
    if (!result)
    {
        qDebug() << shaderProgram.log();
    }

    tLand = new QOpenGLTexture(QImage(":/resource/1.jpg").mirrored());
    tLand->setMinificationFilter(QOpenGLTexture::Nearest);
    tLand->setMagnificationFilter(QOpenGLTexture::Linear);
    tLand->setWrapMode(QOpenGLTexture::Repeat);

    tGrass = new QOpenGLTexture(QImage(":/resource/2.jpg").mirrored());
    tGrass->setMinificationFilter(QOpenGLTexture::Nearest);
    tGrass->setMagnificationFilter(QOpenGLTexture::Linear);
    tGrass->setWrapMode(QOpenGLTexture::Repeat);

    tNoise = new QOpenGLTexture(QImage(":/resource/3.jpg").mirrored());
    tNoise->setMinificationFilter(QOpenGLTexture::Nearest);
    tNoise->setMagnificationFilter(QOpenGLTexture::Linear);
    tNoise->setWrapMode(QOpenGLTexture::Repeat);

    shaderProgram.bind();
    shaderProgram.setUniformValue("textureLand", (GLuint)0);
    shaderProgram.setUniformValue("textureGrass", (GLuint)1);
    shaderProgram.setUniformValue("textureNoise", (GLuint)2);
    shaderProgram.release();
}

void MyOpenGLWidget::resizeGL(int w, int h)
{
    qDebug()<<"new size: w = " << w << ", h = " << h ;
}

void MyOpenGLWidget::paintGL()
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    if (!isDraw) return;

    shaderProgram.bind();
    vao->bind();
    tLand->bind(0);
    tGrass->bind(1);
    tNoise->bind(2);

    //    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

    tGrass->release(1);
    tLand->release(0);
    vao->unbind();
    shaderProgram.release();
}

MyOpenGLWidget::~MyOpenGLWidget()
{
    makeCurrent();
    vao->unbind();
    shaderProgram.release();
    delete vao;
    delete tLand;
    delete tGrass;
    doneCurrent();
}

void MyOpenGLWidget::changeDraw()
{
    isDraw = !isDraw;
    update();
}

void MyOpenGLWidget::changeLine()
{
    isLine = !isLine;
    makeCurrent();
    if (isLine)
    {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }
    else
    {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
    doneCurrent();
    update();
}
